﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Iesi.Collections.Generic;
using Ornament.Domain;
using Ornament.Messages.Dao;

namespace Ornament.Messages
{
    [Serializable]
    public class InfoType : DomainObject<Guid>
    {
        private Iesi.Collections.Generic.ISet<InfoType> childs;
        private IDictionary<string, Template> templates;

        protected InfoType()
        {
        }

        public InfoType(string name)
        {
            Name = name;
        }

        /// <summary>
        /// 
        /// </summary>
        public virtual InfoType Parent { get; protected set; }

        /// <summary>
        /// 
        /// </summary>
        public virtual IInfoDao Info { get; set; }


        /// <summary>
        /// 信息分类
        /// </summary>
        public virtual string Name { get; set; }

        /// <summary>
        /// Gets or sets comment
        /// </summary>
        public virtual string Remark { get; set; }


        /// <summary>
        /// 获取orderId 
        /// </summary>
        public virtual string OrderId { get; protected set; }

        private IDictionary<string, Template> Templates
        {
            get { return templates ?? (templates = new Dictionary<string, Template>()); }
        }

        /// <summary>
        /// 获取InfoType下面的信息
        /// </summary>
        protected Iesi.Collections.Generic.ISet<InfoType> Childs
        {
            get { return childs ?? (childs = new HashedSet<InfoType>()); }
        }

        public virtual int Count
        {
            get { return Childs.Count; }
        }

        public virtual Template CreateTemplate(string name)
        {
            return new Template(this) {Name = name};
        }

        public virtual Template CreateTemplate(string name, string templatePath)
        {
            return new Template(this) {Name = name, Path = templatePath};
        }

        /// <summary>
        /// 获取说有的子InfoType
        /// </summary>
        /// <returns></returns>
        public virtual ReadOnlyCollection<InfoType> GetChilds()
        {
            return new ReadOnlyCollection<InfoType>(new List<InfoType>(Childs));
        }

        public virtual void Add(InfoType child)
        {
            if (Id == Guid.Empty)
                throw new ArgumentNullException("child", "add child InfoType before save this type");
            if (!String.IsNullOrEmpty(OrderId))
                child.OrderId = OrderId + "." + Id;
            else
                child.OrderId = Id.ToString();
            child.Parent = this;
            Childs.Add(child);
        }

        public virtual void Remove(InfoType info)
        {
            Childs.Remove(info);
            info.OrderId = null;
        }


        public override string ToString()
        {
            return Name;
        }

        public override int GetHashCode()
        {
            return Name.GetHashCode();
        }

        public virtual void AddTemplate(Template template)
        {
            if (template.InfoType != this)
                throw new ArgumentNullException("template need to belong to this InfoType");
            Templates.Add(template.Name, template);
        }

        public virtual Template GetTemplate(string templateName)
        {
            return Templates[templateName];
        }
    }
}